package com.ruoyi.basic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.domain.TbCategory;
import com.ruoyi.basic.domain.TbDailyUnitPrice;
import com.ruoyi.basic.domain.TbDailyUnitPriceDetail;
import com.ruoyi.basic.domain.TbDailyUnitPriceDetailReal;
import com.ruoyi.basic.mapper.TbDailyUnitPriceMapper;
import com.ruoyi.basic.service.*;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.enums.BizExceptionEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 定额工日/实际工日单价Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-09-04
 */
@Service
public class TbDailyUnitPriceServiceImpl extends ServiceImpl<TbDailyUnitPriceMapper, TbDailyUnitPrice> implements ITbDailyUnitPriceService
{
    @Autowired
    private ITbDailyUnitPriceDetailService dailyUnitPriceDetailService;
    @Autowired
    private ITbDailyUnitPriceDetailRealService dailyUnitPriceDetailRealService;

    @Override
    public List<TbDailyUnitPrice> listByCondition(TbDailyUnitPrice tbDailyUnitPrice) {
        return baseMapper.selectDailyUnitPriceList(tbDailyUnitPrice);
    }

    @Override
    public boolean deleteByIds(String ids) {
        if(ObjectUtils.isEmpty(ids)){
            throw new ServiceException(BizExceptionEnum.REQUEST_PARAMETER_ERROR.getMessage());
        }
        LambdaQueryWrapper<TbDailyUnitPrice> wrapper = new LambdaQueryWrapper();
        wrapper.in(TbDailyUnitPrice::getId, Arrays.asList(ids.split(",")));
        return remove(wrapper);
    }

    @Override
    public boolean checkCategoryExistByCategoryId(Long id) {
        LambdaQueryWrapper<TbDailyUnitPrice> wrapper = new LambdaQueryWrapper<>();
        // wrapper.eq(TbDailyUnitPrice::getCategoryId,id);
        return count(wrapper) > 0 ? true : false;
    }

    @Override
    public TbDailyUnitPrice getDailyUnitPrice(Long id) {
        TbDailyUnitPrice dailyUnitPrice = getById(id);
        if (Integer.valueOf(1).equals(dailyUnitPrice.getType())) {
            List<TbDailyUnitPriceDetail> detailList = dailyUnitPriceDetailService.listByUnitPriceId(id);
            dailyUnitPrice.setDetailList(detailList);
        }
        if (Integer.valueOf(2).equals(dailyUnitPrice.getType())) {
            List<TbDailyUnitPriceDetailReal> detailList = dailyUnitPriceDetailRealService.listByUnitPriceId(id);
            List<TbDailyUnitPriceDetail> realList = detailList.stream().map(a->{
                TbDailyUnitPriceDetail real = new TbDailyUnitPriceDetail();
                BeanUtils.copyProperties(a,real);
                return real;
            }).collect(Collectors.toList());
            dailyUnitPrice.setDetailList(realList);
        }
        return dailyUnitPrice;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveDailyUnitPrice(TbDailyUnitPrice tbDailyUnitPrice) {
        check(tbDailyUnitPrice);
        List<TbDailyUnitPriceDetail> detailList = tbDailyUnitPrice.getDetailList();
        boolean result = save(tbDailyUnitPrice);
        detailList = detailList.stream().map(a->{
            a.setUnitPriceId(tbDailyUnitPrice.getId());
            a.setType(tbDailyUnitPrice.getType());
        return a;
        }).collect(Collectors.toList());
        if (Integer.valueOf(1).equals(tbDailyUnitPrice.getType())) {
            result = dailyUnitPriceDetailService.saveBatch(detailList);
        }
        if (Integer.valueOf(2).equals(tbDailyUnitPrice.getType())) {
            List<TbDailyUnitPriceDetailReal> realList = detailList.stream().map(a->{
                TbDailyUnitPriceDetailReal real = new TbDailyUnitPriceDetailReal();
                BeanUtils.copyProperties(a,real);
                return real;
            }).collect(Collectors.toList());

            result = dailyUnitPriceDetailRealService.saveBatch(realList);
        }
        return result ? 1 : 0;
    }

    private void check(TbDailyUnitPrice tbDailyUnitPrice) {
        Long categoryId = StringUtils.isNull(tbDailyUnitPrice.getId()) ? -1L : tbDailyUnitPrice.getId();
        TbDailyUnitPrice info = getByUnitPriceDate(tbDailyUnitPrice);
        if (StringUtils.isNotNull(info) && info.getId().longValue() != categoryId.longValue())
        {
            String type = info.getType().intValue() == 1 ? "定额工日单价" : "实际工日单价";
            throw new ServiceException(type + "已经存在");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateDailyUnitPrice(TbDailyUnitPrice tbDailyUnitPrice) {
        check(tbDailyUnitPrice);
        boolean result = updateById(tbDailyUnitPrice);
        List<TbDailyUnitPriceDetail> detailList = tbDailyUnitPrice.getDetailList();
        if (Integer.valueOf(1).equals(tbDailyUnitPrice.getType())) {
            result = dailyUnitPriceDetailService.updateBatchById(detailList);
        }
        if (Integer.valueOf(2).equals(tbDailyUnitPrice.getType())) {
            List<TbDailyUnitPriceDetailReal> realList = detailList.stream().map(a->{
                TbDailyUnitPriceDetailReal real = new TbDailyUnitPriceDetailReal();
                BeanUtils.copyProperties(a,real);
                return real;
            }).collect(Collectors.toList());
            result = dailyUnitPriceDetailRealService.updateBatchById(realList);
        }
        return result ? 1 : 0;
    }

    @Override
    public TbDailyUnitPrice getByUnitPriceDate(TbDailyUnitPrice tbDailyUnitPrice) {
        LambdaQueryWrapper<TbDailyUnitPrice> wrapper = new LambdaQueryWrapper<>();
        wrapper.apply(ObjectUtils.isNotEmpty(tbDailyUnitPrice.getUnitPriceDate())," date_format(unit_price_date,'%Y-%m') = {0} ", DateUtils.parseDateToStr("yyyy-MM",tbDailyUnitPrice.getUnitPriceDate()))
        .eq(ObjectUtils.isNotEmpty(tbDailyUnitPrice.getType()),TbDailyUnitPrice::getType,tbDailyUnitPrice.getType());
        return list(wrapper).isEmpty() ? null : list(wrapper).get(0);
    }

    @Override
    public String checkUnitPriceDateUnique(TbDailyUnitPrice tbDailyUnitPrice) {
        Long categoryId = StringUtils.isNull(tbDailyUnitPrice.getId()) ? -1L : tbDailyUnitPrice.getId();
        TbDailyUnitPrice info = getByUnitPriceDate(tbDailyUnitPrice);
        if (StringUtils.isNotNull(info) && info.getId().longValue() != categoryId.longValue())
        {
            return UserConstants.CATEGORY_NAME_NOT_UNIQUE;
        }
        return UserConstants.CATEGORY_NAME_UNIQUE;
    }

    @Override
    public TbDailyUnitPrice getLast(int type) {
        LambdaQueryWrapper<TbDailyUnitPrice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TbDailyUnitPrice::getType,type).orderByDesc(TbDailyUnitPrice::getUnitPriceDate);
        return ObjectUtils.isEmpty(list(wrapper)) ? new TbDailyUnitPrice() : list(wrapper).get(0);
    }

}
